#include <stdio.h>
#include <string.h>
#include <lua.hpp>
#include <lauxlib.h>
#include <lualib.h>
#include "action_msg.h"
#include <unistd.h>

//待注册的C函数，该函数的声明形式在上面的例子中已经给出。
//需要说明的是，该函数必须以C的形式被导出，因此extern "C"是必须的。
//函数代码和上例相同，这里不再赘述。
extern "C" int add_y(lua_State* L) 
{
    double op1 = luaL_checknumber(L,1);
    double op2 = luaL_checknumber(L,2);
	printf("in add, op1:%f,op2:%f\n",op1,op2);
    lua_pushnumber(L,op1 + op2);
    return 1;
}

extern "C" int sub(lua_State* L)
{
    double op1 = luaL_checknumber(L,1);
    double op2 = luaL_checknumber(L,2);
	printf("in sub, op1:%f,op2:%f\n",op1,op2);
    lua_pushnumber(L,op1 - op2);
    return 1;
}

extern "C" int openlid_y_move(lua_State* L)
{
    unsigned int position = luaL_checknumber(L,1);
    unsigned int speed = luaL_checknumber(L,2);
    unsigned int acc = luaL_checknumber(L,3);
    unsigned int dec = luaL_checknumber(L,4);
	printf("openlid_y_move,pos:%d,speed:%d,acc:%d,dec:%d\n",
    position,speed,acc,dec);
    //call the operation here.
    move_param stParam;
    memset(&stParam,0,sizeof(move_param));
    stParam.dec_speed = dec;
    stParam.inc_speed = acc;
    stParam.pos = position;
    stParam.speed = speed;
    stParam.sid = 11;
    int ret = uimMoveAct_multi(&stParam,1,20000);
    printf("openlid_y_move action end\n");
    lua_pushnumber(L,ret);
    return ret;
}

extern "C" int openlid_z_move(lua_State* L)
{
    unsigned int position = luaL_checknumber(L,1);
    unsigned int speed = luaL_checknumber(L,2);
    unsigned int acc = luaL_checknumber(L,3);
    unsigned int dec = luaL_checknumber(L,4);
	printf("openlid_z_move,pos:%d,speed:%d,acc:%d,dec:%d\n",
    position,speed,acc,dec);
    //call the operation here.
    move_param stParam;
    memset(&stParam,0,sizeof(move_param));
    stParam.dec_speed = dec;
    stParam.inc_speed = acc;
    stParam.pos = position;
    stParam.speed = speed;
    stParam.sid = 10;
    int ret = uimMoveAct_multi(&stParam,1,20000);
    printf("openlid_z_move action end\n");
    lua_pushnumber(L,ret);
    return ret;
}

extern "C" int openlid_jaw_move(lua_State* L)
{
    unsigned int position = luaL_checknumber(L,1);
	printf("openlid_jaw_move,pos:%d\n",
    position);
    //call the operation here.
    move_param stParam;
    memset(&stParam,0,sizeof(move_param));
    stParam.pos = position;
    stParam.sid = 81;
    int ret = uimMoveAct_multi(&stParam,1,20000);
    printf("openlid_jaw_move action end\n");
    lua_pushnumber(L,ret);
    return ret;
}

extern "C" int openlid_y_jaw_move(lua_State* L)
{
    unsigned int position_y = luaL_checknumber(L,1);
    unsigned int position_jaw = luaL_checknumber(L,2);
	printf("openlid_y_jaw_move,pos_y:%d,pos_jaw:%d\n",
    position_y,position_jaw);
    //call the operation here.
    const int actNum = 2;
    move_param stParam[actNum];
    memset(stParam,0,sizeof(move_param)*actNum);
    stParam[0].pos = position_y;
    stParam[0].sid = 11;
    stParam[0].dec_speed = 160000;
    stParam[0].inc_speed = 160000;
    stParam[0].speed = 40000;

    stParam[1].pos = position_jaw;
    stParam[1].sid = 81;

    int ret = uimMoveAct_multi(stParam,2,20000);
    printf("openlid_jaw_move action end\n");
    lua_pushnumber(L,ret);
    return ret;
}


extern "C" int dp1_x_move(lua_State* L)
{
    unsigned int position = luaL_checknumber(L,1);
    unsigned int speed = luaL_checknumber(L,2);
    unsigned int acc = luaL_checknumber(L,3);
    unsigned int dec = luaL_checknumber(L,4);
	printf("dp1_x_move,pos:%d,speed:%d,acc:%d,dec:%d\n",
    position,speed,acc,dec);
    //call the operation here.
    move_param stParam;
    memset(&stParam,0,sizeof(move_param));
    stParam.dec_speed = dec;
    stParam.inc_speed = acc;
    stParam.pos = position;
    stParam.speed = speed;
    stParam.sid = 20;
    int ret = uimMoveAct_multi(&stParam,1,20000);
    printf("dp1_x_move action end\n");
    lua_pushnumber(L,ret);
    return ret;
}

extern "C" int dp1_y_move(lua_State* L)
{
    unsigned int position = luaL_checknumber(L,1);
    unsigned int speed = luaL_checknumber(L,2);
    unsigned int acc = luaL_checknumber(L,3);
    unsigned int dec = luaL_checknumber(L,4);
	printf("dp1_y_move,pos:%d,speed:%d,acc:%d,dec:%d\n",
    position,speed,acc,dec);
    //call the operation here.
    move_param stParam;
    memset(&stParam,0,sizeof(move_param));
    stParam.dec_speed = dec;
    stParam.inc_speed = acc;
    stParam.pos = position;
    stParam.speed = speed;
    stParam.sid = 21;
    int ret = uimMoveAct_multi(&stParam,1,20000);
    printf("dp1_y_move action end\n");
    lua_pushnumber(L,ret);
    return ret;
}

extern "C" int dp1_x_y_move(lua_State* L)
{
    unsigned int position_x = luaL_checknumber(L,1);
    unsigned int position_y = luaL_checknumber(L,2);

	printf("dp1_x_y_move,pos_x:%d,pos_y:%d\n",position_x,position_y);
    //call the operation here.
    move_param stParam[2];
    memset(&stParam,0,sizeof(move_param)*2);
    stParam[0].dec_speed = 160000;
    stParam[0].inc_speed = 160000;
    stParam[0].pos = position_x;
    stParam[0].speed = 35000;
    stParam[0].sid = 20;
    
    stParam[1].dec_speed = 160000;
    stParam[1].inc_speed = 160000;
    stParam[1].pos = position_y;
    stParam[1].speed = 35000;
    stParam[1].sid = 21;
    int ret = uimMoveAct_multi(stParam,2,20000);
    printf("dp1_x_y_move action end\n");
    lua_pushnumber(L,ret);
    return ret;
}

extern "C" int dp1_jawz_move(lua_State* L)
{
    unsigned int position = luaL_checknumber(L,1);
    unsigned int speed = luaL_checknumber(L,2);
    unsigned int acc = luaL_checknumber(L,3);
    unsigned int dec = luaL_checknumber(L,4);
	printf("dp1_jawz_move,pos:%d,speed:%d,acc:%d,dec:%d\n",
    position,speed,acc,dec);
    //call the operation here.
    move_param stParam;
    memset(&stParam,0,sizeof(move_param));
    stParam.dec_speed = dec;
    stParam.inc_speed = acc;
    stParam.pos = position;
    stParam.speed = speed;
    stParam.sid = 22;
    int ret = uimMoveAct_multi(&stParam,1,20000);
    printf("dp1_jawz_move action end\n");
    lua_pushnumber(L,ret);
    return ret;
}

extern "C" int dp1_jaw_move(lua_State* L)
{
    unsigned int position = luaL_checknumber(L,1);
	printf("dp1_jaw_move,pos:%d\n",
    position);
    //call the operation here.
    move_param stParam;
    memset(&stParam,0,sizeof(move_param));
    stParam.pos = position;
    stParam.sid = 80;
    int ret = uimMoveAct_multi(&stParam,1,20000);
    printf("dp1_jaw_move action end\n");
    lua_pushnumber(L,ret);
    return ret;
}

extern "C" int dp8_x_move(lua_State* L)
{
    unsigned int position = luaL_checknumber(L,1);
	printf("dp8_x_move,pos:%d\n",
    position);
    //call the operation here.
    move_param stParam;
    memset(&stParam,0,sizeof(move_param));
    stParam.pos = position;
    stParam.sid = 82;
    int ret = uimMoveAct_multi(&stParam,1,60000);
    printf("dp8_x_move action end\n");
    lua_pushnumber(L,ret);
    return ret;
}

extern "C" int dp8_y_move(lua_State* L)
{
    unsigned int position = luaL_checknumber(L,1);
	printf("dp8_y_move,pos:%d\n",
    position);
    //call the operation here.
    move_param stParam;
    memset(&stParam,0,sizeof(move_param));
    stParam.pos = position;
    stParam.sid = 83;
    int ret = uimMoveAct_multi(&stParam,1,60000);
    printf("dp8_y_move action end\n");
    lua_pushnumber(L,ret);
    return ret;
}

extern "C" int dp8_x_y_move(lua_State* L)
{
    #define ACT_NUM 2
    unsigned int position_x = luaL_checknumber(L,1);
    unsigned int position_y = luaL_checknumber(L,2);
	printf("dp8_x_y_move,pos_x:%d, pos_y:%d\n",
    position_x,position_y);
    //call the operation here.
    move_param stParam[ACT_NUM];
    memset(stParam,0,sizeof(move_param)*ACT_NUM);
    stParam[0].pos = position_x;
    stParam[0].sid = 83;

    stParam[1].pos = position_y;
    stParam[1].sid = 82;   


    int ret = uimMoveAct_multi(stParam,2,70000);
    printf("dp8_x_y_move action end\n");
    lua_pushnumber(L,ret);
    return ret;
}


extern "C" int dp8_z_move(lua_State* L)
{
    unsigned int position = luaL_checknumber(L,1);
    unsigned int speed = luaL_checknumber(L,2);
    unsigned int acc = luaL_checknumber(L,3);
    unsigned int dec = luaL_checknumber(L,4);
	printf("dp8_z_move,pos:%d,speed:%d,acc:%d,dec:%d\n",
    position,speed,acc,dec);
    //call the operation here.
    move_param stParam;
    memset(&stParam,0,sizeof(move_param));
    stParam.dec_speed = dec;
    stParam.inc_speed = acc;
    stParam.pos = position;
    stParam.speed = speed;
    stParam.sid = 15;
    int ret = uimMoveAct_multi(&stParam,1,20000);
    printf("dp8_z_move action end\n");
    lua_pushnumber(L,ret);
    return ret;
}

extern "C" int dp8_suck_move(lua_State* L)
{
    unsigned int position = luaL_checknumber(L,1);
    unsigned int speed = luaL_checknumber(L,2);
    unsigned int acc = luaL_checknumber(L,3);
    unsigned int dec = luaL_checknumber(L,4);
	printf("dp8_suck_move,pos:%d,speed:%d,acc:%d,dec:%d\n",
    position,speed,acc,dec);
    //call the operation here.
    move_param stParam;
    memset(&stParam,0,sizeof(move_param));
    stParam.dec_speed = dec;
    stParam.inc_speed = acc;
    stParam.pos = position;
    stParam.speed = speed;
    stParam.sid = 14;
    int ret = uimMoveAct_multi(&stParam,1,20000);
    printf("dp8_suck_move action end\n");
    lua_pushnumber(L,ret);
    return ret;
}

extern "C" int zr_y_move(lua_State* L)
{
    unsigned int position = luaL_checknumber(L,1);
    unsigned int speed = luaL_checknumber(L,2);
    unsigned int acc = luaL_checknumber(L,3);
    unsigned int dec = luaL_checknumber(L,4);
	printf("zr_y_move,pos:%d,speed:%d,acc:%d,dec:%d\n",
    position,speed,acc,dec);
    //call the operation here.
    move_param stParam;
    memset(&stParam,0,sizeof(move_param));
    stParam.dec_speed = dec;
    stParam.inc_speed = acc;
    stParam.pos = position;
    stParam.speed = speed;
    stParam.sid = 16;
    int ret = uimMoveAct_multi(&stParam,1,20000);
    printf("zr_y_move action end\n");
    lua_pushnumber(L,ret);
    return ret;
}

extern "C" int zr_r_move(lua_State* L)
{
    unsigned int position = luaL_checknumber(L,1);
    unsigned int speed = luaL_checknumber(L,2);
    unsigned int acc = luaL_checknumber(L,3);
    unsigned int dec = luaL_checknumber(L,4);
	printf("zr_r_move,pos:%d,speed:%d,acc:%d,dec:%d\n",
    position,speed,acc,dec);
    //call the operation here.
    move_param stParam;
    memset(&stParam,0,sizeof(move_param));
    stParam.dec_speed = dec;
    stParam.inc_speed = acc;
    stParam.pos = position;
    stParam.speed = speed;
    stParam.sid = 17;
    int ret = uimMoveAct_multi(&stParam,1,20000);
    printf("zr_r_move action end\n");
    lua_pushnumber(L,ret);
    return ret;
}

extern "C" int zr_z_move(lua_State* L)
{
    unsigned int position = luaL_checknumber(L,1);
    unsigned int speed = luaL_checknumber(L,2);
    unsigned int acc = luaL_checknumber(L,3);
    unsigned int dec = luaL_checknumber(L,4);
	printf("zr_z_move,pos:%d,speed:%d,acc:%d,dec:%d\n",
    position,speed,acc,dec);
    //call the operation here.
    move_param stParam;
    memset(&stParam,0,sizeof(move_param));
    stParam.dec_speed = dec;
    stParam.inc_speed = acc;
    stParam.pos = position;
    stParam.speed = speed;
    stParam.sid = 19;
    int ret = uimMoveAct_multi(&stParam,1,20000);
    printf("zr_z_move action end\n");
    lua_pushnumber(L,ret);
    return ret;
}

extern "C" int zr_jaw_move(lua_State* L)
{
    unsigned int position = luaL_checknumber(L,1);
    unsigned int speed = luaL_checknumber(L,2);
    unsigned int acc = luaL_checknumber(L,3);
    unsigned int dec = luaL_checknumber(L,4);
	printf("zr_jaw_move,pos:%d,speed:%d,acc:%d,dec:%d\n",
    position,speed,acc,dec);
    //call the operation here.
    move_param stParam;
    memset(&stParam,0,sizeof(move_param));
    stParam.dec_speed = dec;
    stParam.inc_speed = acc;
    stParam.pos = position;
    stParam.speed = speed;
    stParam.sid = 18;
    int ret = uimMoveAct_multi(&stParam,1,20000);
    printf("zr_jaw_move action end\n");
    lua_pushnumber(L,ret);
    return ret;
}

extern "C" int heat_z_move(lua_State* L)
{
    unsigned int position = luaL_checknumber(L,1);
    unsigned int speed = luaL_checknumber(L,2);
    unsigned int acc = luaL_checknumber(L,3);
    unsigned int dec = luaL_checknumber(L,4);
	printf("heat_z_move,pos:%d,speed:%d,acc:%d,dec:%d\n",
    position,speed,acc,dec);
    //call the operation here.
    move_param stParam;
    memset(&stParam,0,sizeof(move_param));
    stParam.dec_speed = dec;
    stParam.inc_speed = acc;
    stParam.pos = position;
    stParam.speed = speed;
    stParam.sid = 13;
    int ret = uimMoveAct_multi(&stParam,1,20000);
    printf("heat_z_move action end\n");
    lua_pushnumber(L,ret);
    return ret;
}

extern "C" int adp_init(lua_State* L)
{
    unsigned int detectType = luaL_checknumber(L,1);
	printf("adp_init,detect type[%d]\n",
    detectType);

    tecan_init_param stInitParam;
    memset(&stInitParam,0,sizeof(tecan_init_param)); 
    //call the operation here.
    int ret = adpCtl(&stInitParam,TECAN_INIT,30000);
    
    printf("adp_init action end\n");
    lua_pushnumber(L,ret);
    return ret;
}

extern "C" int adp_z_move(lua_State* L)
{
    unsigned int position = luaL_checknumber(L,1);
    unsigned int speed = luaL_checknumber(L,2);
    unsigned int acc = luaL_checknumber(L,3);
    unsigned int dec = luaL_checknumber(L,4);
	printf("adp_z_move,pos:%d,speed:%d,acc:%d,dec:%d\n",
    position,speed,acc,dec);
    //call the operation here.
    move_param stParam;
    memset(&stParam,0,sizeof(move_param));
    stParam.dec_speed = dec;
    stParam.inc_speed = acc;
    stParam.pos = position;
    stParam.speed = speed;
    stParam.sid = 1;
    int ret = adpCtl(&stParam,TECAN_Z_MOVE,20000);
    printf("adp_z_move action end\n");
    lua_pushnumber(L,ret);
    return ret;
}

extern "C" int adp_suck_p(lua_State* L)
{
    unsigned int posPre = luaL_checknumber(L,1);
    float quan = luaL_checknumber(L,2);

	printf("adp_suck_p,posPre:%d,quan:%f\n",
    posPre,quan);
    //call the operation here.
    suck_param stParam;
    memset(&stParam,0,sizeof(suck_param));
    
    stParam.air1Quan = 5;
    stParam.air2Quan = 5;
    stParam.more = 5;
    stParam.posMax = 1550;
    stParam.posPost = 0;
    stParam.posPre = posPre;
    stParam.quantity = quan;
    stParam.speedDetect = 100;
    stParam.speedPost = 2000;
    stParam.speedPre = 2000;
    stParam.speedSuck = 400;
    stParam.spitQuan = 5;
    stParam.stepBelow = 10;
    stParam.threshold = 9;
    
    
    int ret = adpCtl(&stParam,TECAN_SUCK_P,60000);
    printf("adp_suck_p action end\n");
    lua_pushnumber(L,ret);
    return ret;
}

extern "C" int adp_suck_c(lua_State* L)
{
    unsigned int posPre = luaL_checknumber(L,1);
    float quan = luaL_checknumber(L,2);

	printf("adp_suck_c,posPre:%d,quan:%f\n",
    posPre,quan);
    //call the operation here.
    suck_param stParam;
    memset(&stParam,0,sizeof(suck_param));
    
    stParam.air1Quan = 5;
    stParam.air2Quan = 5;
    stParam.more = 5;
    stParam.posMax = 1550;
    stParam.posPost = 0;
    stParam.posPre = posPre;
    stParam.quantity = quan;
    stParam.speedDetect = 100;
    stParam.speedPost = 2000;
    stParam.speedPre = 2000;
    stParam.speedSuck = 400;
    stParam.spitQuan = 5;
    stParam.stepBelow = 10;
    stParam.threshold = 18;
    
    
    int ret = adpCtl(&stParam,TECAN_SUCK_EXT,60000);
    printf("adp_suck_c action end\n");
    lua_pushnumber(L,ret);
    return ret;
}

extern "C" int adp_spit(lua_State* L)
{
    unsigned int posPre = luaL_checknumber(L,1);
    float quan = luaL_checknumber(L,2);

	printf("adp_suck_c,posPre:%d,quan:%f\n",
    posPre,quan);
    //call the operation here.
    tecan_liquid_param stParam;
    memset(&stParam,0,sizeof(suck_param));
    

    stParam.posMax = 1550;
    stParam.posPost = 0;
    stParam.posPre = posPre;
    stParam.quantity = quan;
    stParam.quanSpitAir1 = 5;

    stParam.quanSuckBack = 5;
    stParam.speed = 32000;    
    
    int ret = adpCtl(&stParam,TECAN_SPIT,60000);
    printf("adp_suck_c action end\n");
    lua_pushnumber(L,ret);
    return ret;
}

extern "C" int sleep_ms(lua_State* L)
{
    unsigned int duration_ms = luaL_checknumber(L,1);

    usleep(duration_ms*1000);
    return 0;
}

//luaL_Reg结构体的第一个字段为字符串，在注册时用于通知Lua该函数的名字。
//第一个字段为C函数指针。
//结构体数组中的最后一个元素的两个字段均为NULL，用于提示Lua注册函数已经到达数组的末尾。
static luaL_Reg mylibs[] = { 
    {"add_y", add_y},
    {"sub", sub},
    {"openlid_y_move",openlid_y_move},
    {"openlid_z_move",openlid_z_move},
    {"openlid_jaw_move",openlid_jaw_move},
    {"openlid_y_jaw_move",openlid_y_jaw_move},
    {"dp1_x_move",dp1_x_move},
    {"dp1_y_move",dp1_y_move},
    {"dp1_jawz_move",dp1_jawz_move},
    {"dp1_jaw_move",dp1_jaw_move},    
    {"dp1_x_y_move",dp1_x_y_move},
    {"dp8_x_move",dp8_x_move},
    {"dp8_y_move",dp8_y_move},
    {"dp8_x_y_move",dp8_x_y_move},
    {"dp8_z_move",dp8_z_move},
    {"dp8_suck_move",dp8_suck_move},    
    {"zr_y_move",zr_y_move},
    {"zr_z_move",zr_z_move},
    {"zr_r_move",zr_r_move},    
    {"zr_jaw_move",zr_jaw_move},
    {"heat_z_move",heat_z_move},
    {"adp_init",adp_init},    
    {"adp_z_move",adp_z_move},
    {"adp_suck_p",adp_suck_p},
    {"adp_suck_c",adp_suck_c},
    {"adp_spit",adp_spit},
    {"sleep_ms",sleep_ms},
    {NULL, NULL} 
}; 

//该C库的唯一入口函数。其函数签名等同于上面的注册函数。见如下几点说明：
//1. 我们可以将该函数简单的理解为模块的工厂函数。
//2. 其函数名必须为luaopen_xxx，其中xxx表示library名称。Lua代码require "xxx"需要与之对应。
//3. 在luaL_register的调用中，其第一个字符串参数为模块名"xxx"，第二个参数为待注册函数的数组。
//4. 需要强调的是，所有需要用到"xxx"的代码，不论C还是Lua，都必须保持一致，这是Lua的约定，
//   否则将无法调用。
#ifdef __WIN32
extern "C" __declspec(dllexport)
#else
extern "C"
#endif 
int luaopen_mytestlib(lua_State* L) 
{
    //const char* libName = "mytestlib";
    //luaL_register(L,libName,mylibs);
    printf("register functions here\n");
	luaL_newlib(L,mylibs);
    return 1;
}


int register_mytestlib(lua_State* L) 
{
    //const char* libName = "mytestlib";
    //luaL_register(L,libName,mylibs);
    printf("register functions here\n");
	//luaL_newlib(L,mylibs);
    luaL_Reg * ptrFuncs = mylibs;
    while(ptrFuncs->name != NULL)
    {
        lua_register(L,ptrFuncs->name,ptrFuncs->func);
        ptrFuncs++;
    }
    return 1;
}